package org.andao.core.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * 简单的浏览器模拟器.
 * 
 */
public class SimpleBrowserMock {		
	
	protected Map<String,String> headers = new HashMap<String,String>(0);	
	private URL url;
	private String body;
	
	
	public SimpleBrowserMock(){}
	
	public SimpleBrowserMock(URL url){
		this.url  = url;
	}
			
	public SimpleBrowserMock header(final String key,final String value){
		headers.put(key, value);
		return this;
	}
					
	public  String doGetForm() throws IOException{		
		 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		 if(!headers.isEmpty())
			 setHeader(connection);
		 connection.connect();
		 StringBuilder sb = new StringBuilder();
		 responseReader(sb,connection);
	     connection.disconnect();	    
		 return sb.toString();
	}
	
	public String doPostForm() throws Exception{
		return doPostForm(body);
	}
	
	public  String doPostForm(String formContent) throws Exception{		
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
				
		connection.setDoOutput(true);
		connection.setRequestProperty("Accept", "*/*");
		connection.setRequestProperty("Charsert", "UTF-8");
		connection.setRequestMethod("POST");
		connection.setUseCaches(false);
		connection.setRequestProperty("Connection", "Keep-Alive");
		connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
		
		if(!headers.isEmpty())
			 setHeader(connection);
		connection.connect();
		
		OutputStream  out = connection.getOutputStream();
	
		out.write(formContent.getBytes("UTF-8"));		
		out.flush();
		out.close();
		
		//读取服务器response		
		 StringBuilder sb = new StringBuilder();
		 responseReader(sb,connection);
	     connection.disconnect();
	     return sb.toString();
	}
	
	/**
	 * 上传文件到服务器，并接受服务器发回的文件.<p>
	 * 典型用例:client -->send file -->server convert file --> send converted file to client.
	 * @param uploadUrl 上传服务器地址.
	 * @param srcFile 本地上传的文件.ex./home/marco/test/tt.pptx
	 * @param distFile 接受服务器文件后保存的路径.ex./home/marco/test/tt.zip
	 */
	public  File uploadAndReciveFile(File srcfile,File distFile)	throws Exception {
		HttpURLConnection con = (HttpURLConnection) url.openConnection();
		
		// 设置连接参数属性
		con.setDoOutput(true);  
		con.setDoInput(true);  
		con.setUseCaches(false); 
		con.setRequestMethod("POST");
		con.setRequestProperty("Accept", "*/*");
		con.setRequestProperty("Accept-Language", "zh-cn");
		con.setRequestProperty("Charsert", "UTF-8");
		con.setRequestProperty("Content-Type",	"multipart/form-data; boundary=---------------------------8d71b5d6290e4");
		con.setRequestProperty("Accept-Encoding", "gzip, deflate");
		con.setRequestProperty("Connection", "Keep-Alive");
		con.setRequestProperty("Cache-Control", "no-cache");
		
		// 设置流式输出的请求头和请求尾
		String header = "-----------------------------8d71b5d6290e4\r\n"
				+ "Content-Disposition: form-data; name=\"file\"; filename=\""+srcfile.getName()+"\"\r\n"
				+ "Content-Type: application/octet-stream\r\n\r\n";
		byte[] tail = "\r\n-----------------------------8d71b5d6290e4--\r\n".getBytes();
		byte[] headByte = String.format(header, srcfile.getName()).getBytes();
		// 设置请求体的长度(直接输出,避免在本地进行缓存),同时连接服务器
		con.setFixedLengthStreamingMode((int) srcfile.length() + headByte.length+ tail.length);
		
		if(!headers.isEmpty())
			 setHeader(con);
		con.connect();
		// 写文件流到请求体中
		OutputStream dos = con.getOutputStream();		
		dos.write(headByte); // 写文件头
		FileInputStream fis = new FileInputStream(srcfile);
		int len = 0;
		byte b[] = new byte[4096];
		while (len != -1) {
			len = fis.read(b);
			if (len > 0) {
				dos.write(b, 0, len);
				dos.flush();
				//uploadStatus.upload(len);
			}
		}
		fis.close();
		dos.write(tail);
		dos.close();
		//uploadStatus.dataTransportComplete(); // 数据传输完毕

		// 获取响应流
		InputStream is = con.getInputStream();
		OutputStream out = new FileOutputStream(distFile);
		int read = 0;
		byte[] bytes = new byte[1024];
 		
		while ((read = is.read(bytes)) != -1) {
			out.write(bytes, 0, read);
		}
		out.flush();
		out.close();	
	
		return distFile;
	}	
	
	private void setHeader(HttpURLConnection con){
		for(String key : headers.keySet()){
			con.setRequestProperty(key, headers.get(key));
		}
	}

	private StringBuilder responseReader(StringBuilder sb,HttpURLConnection connect) throws  IOException{
		 BufferedReader reader = new BufferedReader(new InputStreamReader(connect.getInputStream(),"utf-8"));
		 String lines;		
	     while ((lines = reader.readLine()) != null) {
	    	 sb.append(new String(lines.getBytes("UTF-8"), "UTF-8"));
	     }
	     reader.close();
	     return sb;
	} 
	
	public URL getUrl() {
		return url;
	}

	public void setUrl(URL url) {
		this.url = url;
	}

	public String getBody() {
		return body;
	}

	public void setBody(String body) {
		this.body = body;
	}
	
	
		
}	
